﻿namespace EasyWeb
{
    using System.ComponentModel.DataAnnotations;
    using System.Data;
    using EasyWeb.Data;
    using EasyWeb.Design;
    using EasyWeb.Validation;

    [EWDisplayName(Name = "FieldDefinitionNumber", ResourceType = typeof(EWFieldDefinitionResources))]
    public class EWFieldDefinitionNumber : EWFieldDefinition
    {
        [Display(ResourceType = typeof(EWFieldDefinitionResources), Name = "FieldDefinition_AllowDefaultValue")]
        public override bool AllowDefaultValue
        {
            get { return true; }
        }

        [Display(ResourceType = typeof(EWFieldDefinitionResources), Name = "FieldDefinition_AllowUnique")]
        public override bool AllowUnique
        {
            get { return true; }
        }

        [Display(ResourceType = typeof(EWFieldDefinitionResources), Name = "FieldDefinition_DefaultValue")]
        public override object DefaultValue
        {
            get { return this.StateBag.Get<decimal?>("DefaultValue"); }
            set { this.StateBag.Set("DefaultValue", (decimal?)value); }
        }

        [Display(ResourceType = typeof(EWFieldDefinitionResources), Name = "FieldDefinitionNumber_MinimumValue")]
        [EWPropertyCompareValidation("MaximumValue", EWCompareMode.LessThanOrEquals)]
        public decimal? MinimumValue
        {
            get { return this.StateBag.Get<decimal?>("MinimumValue"); }
            set { this.StateBag.Set("MinimumValue", value); }
        }

        [Display(ResourceType = typeof(EWFieldDefinitionResources), Name = "FieldDefinitionNumber_MaximumValue")]
        public decimal? MaximumValue
        {
            get { return this.StateBag.Get<decimal?>("MaximumValue"); }
            set { this.StateBag.Set("MaximumValue", value); }
        }

        [Display(ResourceType = typeof(EWFieldDefinitionResources), Name = "FieldDefinitionNumber_NumberFormat")]
        public EWNumberFormat NumberFormat
        {
            get { return this.StateBag.Get<EWNumberFormat>("NumberFormat", () => EWNumberFormat.Integer); }
            set
            {
                EWGuard.IsDefinedEnum(value, "value");
                this.StateBag.Set("NumberFormat", value);
            }
        }

        [Display(ResourceType = typeof(EWFieldDefinitionResources), Name = "FieldDefinitionNumber_DisplayMode")]
        public EWNumberDisplayMode DisplayMode
        {
            get { return this.StateBag.Get<EWNumberDisplayMode>("DisplayMode", () => EWNumberDisplayMode.Automatic); }
            set
            {
                EWGuard.IsDefinedEnum(value, "value");
                this.StateBag.Set("DisplayMode", value);
            }
        }

        public override EWFieldDefinitionColumnCollection CreateFieldDefinitionColumns()
        {
            var field = new EWFieldDefinitionColumn()
            {
                Name = this.InternalName,
                IsNullable = this.AllowNull,
                IsUnique = this.AllowUnique && this.IsUnique,
            };

            switch (this.NumberFormat)
            {
                case EWNumberFormat.Integer:
                    field.Type = DbType.Int64;
                    break;
                case EWNumberFormat.Float:
                    field.Type = DbType.Decimal;
                    break;
            }

            return new EWFieldDefinitionColumnCollection()
            {
                field
            };
        }

        public override void Deserialize(EWSerializationInfo info)
        {
            base.Deserialize(info);

            this.MaximumValue = info.GetNullableDecimal("MaximumValue");
            this.MinimumValue = info.GetNullableDecimal("MinimumValue");
            this.NumberFormat = info.GetEnum<EWNumberFormat>("NumberFormat");
            this.DisplayMode = info.GetEnum<EWNumberDisplayMode>("DisplayMode");
            this.DefaultValue = info.GetNullableDecimal("DefaultValue");
        }

        public override void Serialize(EWSerializationInfo info)
        {
            base.Serialize(info);

            info.AddValue("MaximumValue", this.MaximumValue);
            info.AddValue("MinimumValue", this.MinimumValue);
            info.AddValue("NumberFormat", this.NumberFormat);
            info.AddValue("DisplayMode", this.DisplayMode);
            info.AddValue("DefaultValue", (decimal?)this.DefaultValue);
        }
    }
}
